﻿using Microsoft.Extensions.Logging;
using SqlSugar;

namespace Net8.Project.Data.UnitOfWorks
{
    /// <summary>
    /// 工作单元实现，封装事务管理和数据库连接管理
    /// </summary>
    public class UnitOfWork : IDisposable
    {
        /// <summary>
        /// 日志记录器
        /// </summary>
        public ILogger Logger { get; set; }

        /// <summary>
        /// SqlSugar数据库客户端
        /// </summary>
        public ISqlSugarClient Db { get; internal set; }

        /// <summary>
        /// 多租户支持接口
        /// </summary>
        public ITenant Tenant { get; internal set; }

        /// <summary>
        /// 是否开启事务
        /// </summary>
        public bool IsTran { get; internal set; }

        /// <summary>
        /// 事务是否已提交
        /// </summary>
        public bool IsCommit { get; internal set; }

        /// <summary>
        /// 数据库连接是否已关闭
        /// </summary>
        public bool IsClose { get; internal set; }

        /// <summary>
        /// 释放资源，自动回滚未提交的事务并关闭数据库连接
        /// </summary>
        public void Dispose()
        {
            // 如果开启了事务但未提交，则回滚事务
            if (this.IsTran && !this.IsCommit)
            {
                Logger.LogDebug("UnitOfWork RollbackTran");
                this.Tenant.RollbackTran();
            }

            // 如果事务还存在或已关闭则不再关闭连接
            if (this.Db.Ado.Transaction != null || this.IsClose)
                return;
            // 关闭数据库连接
            this.Db.Close();
        }

        /// <summary>
        /// 提交事务并关闭数据库连接
        /// </summary>
        /// <returns>事务是否已提交</returns>
        public bool Commit()
        {
            // 如果开启了事务且未提交，则提交事务
            if (this.IsTran && !this.IsCommit)
            {
                Logger.LogDebug("UnitOfWork CommitTran");
                this.Tenant.CommitTran();
                this.IsCommit = true;
            }

            // 如果没有事务且未关闭，则关闭数据库连接
            if (this.Db.Ado.Transaction == null && !this.IsClose)
            {
                this.Db.Close();
                this.IsClose = true;
            }

            return this.IsCommit;
        }
    }
}
